#ifndef __INCLUDED_CBL_SIMD_H__
#error "CBL_SIMD_Altivec.hpp must not be used directly. Use CBL_SIMD.h instead."
#else
#ifndef __INCLUDED_CBL_SIMD_ALTIVEC_HPP__
#define __INCLUDED_CBL_SIMD_ALTIVEC_HPP__


// ---------------------------------------------------------------------------------------------
//  Vec4f declarations
// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSplat(Vec4f& _rOut, float _Value)
{
	_rOut.Packed = (vector float)(_Value);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSplat(Vec4f& _rOut, Vec4f& _rValues, uint32 _Selector)
{
	_rOut.Packed = (vector float)(_rValues.Data[_Selector], _rValues.Data[_Selector], 
								  _rValues.Data[_Selector], _rValues.Data[_Selector]);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSwizzle(Vec4f& _rOut, const Vec4f& _rValues, const Vec4i& _rDest)
{
	_rOut.Packed = vec_perm(_rValues.Packed, _rValues.Packed, _rDest.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMergeBack(Vec4f& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Data[0] = _rLhs.Data[2];
	_rOut.Data[1] = _rRhs.Data[2];
	_rOut.Data[2] = _rLhs.Data[3];
	_rOut.Data[3] = _rRhs.Data[3];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMergeFront(Vec4f& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Data[0] = _rLhs.Data[0];
	_rOut.Data[1] = _rRhs.Data[0];
	_rOut.Data[2] = _rLhs.Data[1];
	_rOut.Data[3] = _rRhs.Data[1];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAdd(Vec4f& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_add(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSub(Vec4f& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_sub(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMul(Vec4f& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_madd(_rLhs.Packed, _rRhs.Packed, (vector float)(0));
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecDiv(Vec4f& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_madd(_rLhs.Packed, vec_re(_rRhs.Packed), (vector float)(0));
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMAdd(Vec4f& _rOut, const Vec4f& _rMLhs, const Vec4f& _rMRhs, const Vec4f& _rAdd)
{
	_rOut.Packed = vec_madd(_rMLhs.Packed, _rMRhs.Packed, _rAdd.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecNMSub(Vec4f& _rOut, const Vec4f& _rMLhs, const Vec4f& _rMRhs, const Vec4f& _rSub)
{
	_rOut.Packed = vec_nmsub(_rMLhs.Packed, _rMRhs.Packed, _rSub.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecScale(Vec4f& _rOut, const Vec4f& _rLhs, float _Scale)
{
	_rOut.Packed = vec_madd(_rLhs.Packed, (vector float)(_Scale), (vector float)(0));
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMin(Vec4f& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_min(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMax(Vec4f& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_max(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSqrt(Vec4f& _rOut, const Vec4f& _rValues)
{
	_rOut.Packed = vec_re(vec_rsqrte(_rValues.Packed));
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecRESqrt(Vec4f& _rOut, const Vec4f& _rValues)
{
	_rOut.Packed = vec_rsqrte(_rValues.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecRE(Vec4f& _rOut, const Vec4f& _rValues)
{
	_rOut.Packed = vec_re(_rValues.Packed);	
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAbs(Vec4f& _rOut, const Vec4f& _rValues)
{
	_rOut.Packed = vec_abs(_rValues.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecFloor(Vec4f& _rOut, const Vec4f& _rValues)
{
	_rOut.Packed = vec_floor(_rValues.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCeil(Vec4f& _rOut, const Vec4f& _rValues)
{
	_rOut.Packed = vec_ceil(_rValues.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecRound(Vec4f& _rOut, const Vec4f& _rValues)
{
	_rOut.Packed = vec_round(_rValues.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE bool CB_INLINE_ATTR VecAll(const Vec4f& _rValues, float _Value)
{
	return (bool)vec_all_eq(_rValues.Packed, (vector float)(_Value));
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpEQ(Vec4i& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_cmpeq(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpGT(Vec4i& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_cmpgt(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpLT(Vec4i& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_cmplt(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpGE(Vec4i& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_cmpge(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpLE(Vec4i& _rOut, const Vec4f& _rLhs, const Vec4f& _rRhs)
{
	_rOut.Packed = vec_cmple(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------
//  Vec4i declarations
// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSplat(Vec4i& _rOut, int32 _Value)
{
	_rOut.Packed = (vector int)(_Value);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSplat(Vec4i& _rOut, Vec4i& _rValues, uint32 _Selector)
{
	_rOut.Packed = (vector char)(	_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector]);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSwizzle(Vec4i& _rOut, const Vec4i& _rValues, const Vec4i& _rDest)
{
	_rOut.Packed = vec_perm(_rValues.Packed, _rValues.Packed, _rDest.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMergeBack(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Data[0] = _rLhs.Data[2];
	_rOut.Data[1] = _rRhs.Data[2];
	_rOut.Data[2] = _rLhs.Data[3];
	_rOut.Data[3] = _rRhs.Data[3];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMergeFront(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Data[0] = _rLhs.Data[0];
	_rOut.Data[1] = _rRhs.Data[0];
	_rOut.Data[2] = _rLhs.Data[1];
	_rOut.Data[3] = _rRhs.Data[1];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAdd(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_add(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSub(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_sub(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMul(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	for (int32 i(0); i<4; ++i)
		_rOut.Data[i] = _rLhs.Data[i] * _rRhs.Data[i];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecDiv(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	for (int32 i(0); i<4; ++i)
		_rOut.Data[i] = _rLhs.Data[i] / _rRhs.Data[i];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMAdd(Vec4i& _rOut, const Vec4i& _rMLhs, const Vec4i& _rMRhs, const Vec4i& _rAdd)
{
	CB_DECL_ALIGN(16) Vec4i Temp;
	VecMul(Temp, _rMLhs, _rMRhs);
	_rOut.Packed = vec_add(Temp.Packed, _rAdd.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecScale(Vec4i& _rOut, const Vec4i& _rLhs, int32 _Scale)
{
	for (int32 i(0); i<4; ++i)
		_rOut.Data[i] = _rLhs.Data[i] * _Scale;
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMin(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_min(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMax(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_max(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAnd(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_and(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAndNot(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_andc(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecOr(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_or(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecXOr(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_xor(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecLShift(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	for (int32 i(0); i<4; ++i)
		_rOut.Data[i] = _rLhs.Data[i] << _rRhs.Data[i];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecRShift(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	for (int32 i(0); i<4; ++i)
		_rOut.Data[i] = _rLhs.Data[i] >> _rRhs.Data[i];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAbs(Vec4i& _rOut, const Vec4i& _rValues)
{
	_rOut.Packed = vec_abs(_rValues.Packed);
}


// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE bool CB_INLINE_ATTR VecAll(const Vec4i& _rValues, int32 _Value)
{
	return (bool)vec_all_eq(_rValues.Packed, (vector int)(_Value));
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpEQ(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_cmpeq(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpGT(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_cmpgt(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpLT(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i&_rRhs)
{
	_rOut.Packed = vec_cmplt(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpGE(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_cmpge(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpLE(Vec4i& _rOut, const Vec4i& _rLhs, const Vec4i& _rRhs)
{
	_rOut.Packed = vec_cmple(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------
//  Vec8s declarations
// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSplat(Vec8s& _rOut, int16 _Value)
{
	_rOut.Packed = (vector short)(_Value);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSplat(Vec8s& _rOut, Vec8s& _rValues, uint32 _Selector)
{
	_rOut.Packed = (vector char)(	_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector]);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSwizzle(Vec8s& _rOut, const Vec8s& _rValues, const Vec8s& _rDest)
{
	_rOut.Packed = vec_perm(_rValues.Packed, _rValues.Packed, _rDest.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMergeBack(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	for (int i(0); i<8; ++i)
	{
		int j=4+i/2;
		_rOut.Data[i] = _rLhs.Data[j];
		_rOut.Data[++i] = _rRhs.Data[j];
	}
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMergeFront(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	for (int i(0); i<8; ++i)
	{
		int j=i/2;
		_rOut.Data[i] = _rLhs.Data[j];
		_rOut.Data[++i] = _rRhs.Data[j];
	}
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAdd(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_add(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSub(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_sub(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMul(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	for (int32 i(0); i<8; ++i)
		_rOut.Data[i] = _rLhs.Data[i] * _rRhs.Data[i];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecDiv(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	for (int32 i(0); i<8; ++i)
		_rOut.Data[i] = _rLhs.Data[i] / _rRhs.Data[i];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMAdd(Vec8s& _rOut, const Vec8s& _rMLhs, const Vec8s& _rMRhs, const Vec8s& _rAdd)
{
	CB_DECL_ALIGN(16) Vec8s Temp;
	VecMul(Temp, _rMLhs, _rMRhs);
	_rOut.Packed = vec_add(Temp.Packed, _rAdd.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecScale(Vec8s& _rOut, const Vec8s& _rLhs, int16 _Scale)
{
	for (int32 i(0); i<8; ++i)
		_rOut.Data[i] = _rLhs.Data[i] * _Scale;
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMin(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_min(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMax(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_max(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAnd(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_and(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAndNot(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_andc(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecOr(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_or(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecXOr(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_xor(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecLShift(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	for (int32 i(0); i<8; ++i)
		_rOut.Data[i] = _rLhs.Data[i] << _rRhs.Data[i];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecRShift(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	for (int32 i(0); i<8; ++i)
		_rOut.Data[i] = _rLhs.Data[i] >> _rRhs.Data[i];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAbs(Vec8s& _rOut, const Vec8s& _rValues)
{
	_rOut.Packed = vec_abs(_rValues.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE bool CB_INLINE_ATTR VecAll(const Vec8s& _rValues, int16 _Value)
{
	return (bool)vec_all_eq(_rValues.Packed, (vector short)(_Value));
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpEQ(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_cmpeq(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpGT(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_cmpgt(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpLT(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_cmplt(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpGE(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_cmpgt(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpLE(Vec8s& _rOut, const Vec8s& _rLhs, const Vec8s& _rRhs)
{
	_rOut.Packed = vec_cmple(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------
//  Vec16c declarations
// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSplat(Vec16c& _rOut, int8 _Value)
{
	_rOut.Packed = (vector char)(_Value);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSplat(Vec16c& _rOut, Vec16c& _rValues, uint32 _Selector)
{
	_rOut.Packed = (vector char)(	_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector], 
									_rValues.Data[_Selector], _rValues.Data[_Selector]);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSwizzle(Vec16c& _rOut, const Vec16c& _rValues, const Vec16c& _rDest)
{
	_rOut.Packed = vec_perm(_rValues.Packed, _rValues.Packed, _rDest.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMergeBack(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_mergel(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMergeFront(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_mergeh(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAdd(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_add(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecSub(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_sub(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMul(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	for (int32 i(0); i<16; ++i)
		_rOut.Data[i] = _rLhs.Data[i] * _rRhs.Data[i];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecDiv(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	for (int32 i(0); i<16; ++i)
		_rOut.Data[i] = _rLhs.Data[i] / _rRhs.Data[i];
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMAdd(Vec16c& _rOut, const Vec16c& _rMLhs, const Vec16c& _rMRhs, const Vec16c& _rAdd)
{
	CB_DECL_ALIGN(16) Vec16c Temp;
	VecMul(Temp, _rMLhs, _rMRhs);
	_rOut.Packed = vec_add(Temp.Packed, _rAdd.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecScale(Vec16c& _rOut, const Vec16c& _rLhs, int8 _Scale)
{
	for (int32 i(0); i<16; ++i)
		_rOut.Data[i] = _rLhs.Data[i] * _Scale;
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMin(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_min(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecMax(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_max(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAnd(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_and(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAndNot(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_andc(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecOr(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_or(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecXOr(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_xor(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecLShift(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_sl(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecRShift(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_sr(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecAbs(Vec16c& _rOut, const Vec16c& _rValues)
{
	_rOut.Packed = vec_abs(_rValues.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE bool CB_INLINE_ATTR VecAll(const Vec16c& _rValues, int8 _Value)
{
	return (bool)vec_all_eq(_rValues.Packed, (vector char)(_Value));
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpEQ(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_cmpeq(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpGT(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_cmpgt(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpLT(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_cmplt(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpGE(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_cmpge(_rLhs.Packed, _rRhs.Packed);
}

// ---------------------------------------------------------------------------------------------

CB_FORCEINLINE void CB_INLINE_ATTR VecCmpLE(Vec16c& _rOut, const Vec16c& _rLhs, const Vec16c& _rRhs)
{
	_rOut.Packed = vec_cmple(_rLhs.Packed, _rRhs.Packed);
}

#endif
#endif